
from io import BytesIO
import random
import time
import tkinter as tk
import datetime
from tkinter import ttk
from PIL import Image, ImageTk

import threading
import certifi
import requests  # 导入多线程模块

# 时间显示
time_text = None
# 时间线程标志
time_start = True
# 当前时间
now = None
T = None


arr = []
arr_index = 0
prize_ids = {
    '10': '82647d4206bb9b6b4ce8de4539392457',
    '50': 'a6d891276c5249b56c41cbd8d493dd98',
    "100": 'a369c8f69a7e8b0f08b41d71efd2f95f',
    "300": 'f1de5dbcbddcc3c1a381386b76083f04'
}
# 伪装浏览器头部
headers = {
    'Host': 'g.qll-times.com',
    'Accept': 'application/json, text/plain, */*',
    'business-id': 'QebnM7',
    'version': '1706855993.346',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
    'Content-Type': 'application/json;charset=utf-8',
    'Origin': 'https://g.qll-times.com',
    'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 15_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.45(0x18002d2c) NetType/WIFI Language/zh_CN miniProgram/wx6f17e7e23765ca30',
    'Referer': 'https://g.qll-times.com/act/QebnM7/XYkDkATq/?v=2',
    'Connection': 'keep-alive',
    'Cookie': ''
}
activity_id = 'XYkDkATq'
offset_y = 0
sms_num = 0

########################################################################


def get_time():
    start_time = datetime.datetime.now()
    url = 'https://www.jishirili.com/time.asp'
    response = requests.get(url, verify=certifi.where())
    response.close()
    if response.status_code == 200:
        timestamp_ms = response.json()
        # 将毫秒转换为秒
        timestamp_sec = timestamp_ms / 1000

        # 将时间戳转换为日期时间对象
        datetime_obj = datetime.datetime.fromtimestamp(timestamp_sec)
        end_time = datetime.datetime.now()
        execution_time = (end_time - start_time)

        return execution_time+datetime_obj
    else:
        return None


def start_time_thread():
    global T
    T = threading.Thread(target=start_time_ling, args=())  # 多线程
    T.daemon = True  # 线程守护，即主进程结束后，此线程也结束。否则主进程结束子进程不结束
    T.start()  # 启动


def start_time_ling():
    global time_start
    global time_text
    global now
    time_start = True
    now = get_time()
    while time_start:
        start_time = datetime.datetime.now()
        timer = '{}'.format(now)[:-5]
        time_text.config(text=timer)
        time.sleep(0.01)
        end_time = datetime.datetime.now()
        execution_time = (end_time - start_time)
        now = execution_time+now
########################################################################


def play_order(k):
    global activity_id
    params = {'activity_id': activity_id}
    url = 'https://g.qll-times.com/api/generate/image/captcha'
    header = headers.copy()
    header['Cookie'] = arr[k]['cookie']
    response = requests.get(url, headers=header,
                            params=params, verify=certifi.where())
    response.close()
    if response.status_code == 200:
        json_response = response.json()
        image_url = json_response['data']['image_url']
        captcha_data = json_response['data']['captcha_data']
        return image_url, captcha_data

    else:
        return None, None


def wait_cahe(k):
    global now
    arr[k]['switch'] = True

    while arr[k]['switch']:
        ti = arr[k]['start_time']
        if now >= ti:
            arr[k]['switch'] = False
            timer = '开始抢劵 {}'.format(now)
            print(timer)
            arr[k]['logbel'].config(text=timer)
            submit_cache(k)
        time.sleep(0.005)


def submit_cache(k):
    try:
        url = 'https://g.qll-times.com/api/activity/prize/receive/cache'
        data = {"activity_id": activity_id,
                "prize_id": prize_ids[arr[k]['prize_id']],
                "phone_number": "11111111111",
                "user_answer_data": arr[k]['texts']}
        header = headers.copy()
        header['Cookie'] = arr[k]['cookie']
        print(header, data)
        response = requests.post(
            url, headers=header, json=data, verify=certifi.where())
        response.close()
        if response.status_code == 200:
            json_response = response.json()
            arr[k]['logbel'].config(text=json_response)
            print(json_response)
    except Exception:
        arr[k]['logbel'].config(text='重试')


def start_thread(k):
    arr[k]['threading'] = threading.Thread(target=wait_cahe, args=(k,))  # 多线程
    arr[k]['threading'].daemon = True  # 线程守护，即主进程结束后，此线程也结束。否则主进程结束子进程不结束
    arr[k]['threading'].start()  # 启动


def play_sms(k):
    text = []
    for item in arr[k]['texts']:
        text.append(item["character"])
      # 下载图片
    response = requests.get(arr[k]['image_url'])
    image_data = response.content

    # 使用PIL打开图像
    image = Image.open(BytesIO(image_data))

    # 创建子窗口
    top = tk.Toplevel()
    top.title(text)

    # 创建Canvas
    canvas = tk.Canvas(top, width=image.width, height=image.height)
    canvas.pack()

    # 将图像转换为Tkinter可用的格式
    tk_image = ImageTk.PhotoImage(image)

    # 在Canvas上显示图片
    canvas.create_image(0, 0, anchor=tk.NW, image=tk_image)
    # 管理 tk_image 的生命周期
    top.tk_image = tk_image

    def on_click(event):
        global sms_num  # 声明 num 为全局变量
        # 打印点击的坐标
        x = '{:.2f}'.format(float(event.x))
        y = '{:.2f}'.format(float(event.y))
        print(
            f"Clicked{sms_num} at: x={x}, y={y}")
        for item in arr[k]['texts']:
            if item["index"] == sms_num:
                item["x"] = x
                item["y"] = y
                sms_num = sms_num+1
                submit_text.config(text=arr[k]['texts'])
                break
    canvas.bind("<Button-1>", on_click)

    # 创建提交按钮
    def submit():
        global sms_num  # 声明 num 为全局变量
        sms_num = 0  # 声明 num 为全局变量
        arr[k]['logbel'].config(text='验证码已提交')
        top.destroy()
        start_thread(k)

    submit_text = tk.Label(top, wraplength=200, justify="left", text=sms_num)
    submit_text.pack()
    submit_button = tk.Button(top, text="提交", command=submit)
    submit_button.pack()


def create_windows():
    '''初始化窗口'''

    root = tk.Tk()
    root .title("脚本")
    sw = root.winfo_screenwidth()
    # 得到屏幕宽度
    sh = root.winfo_screenheight()

    # 得到屏幕高度
    ww = 1366
    wh = 768

    x = (sw - ww) / 2
    y = (sh - wh) / 2
    root.geometry("%dx%d+%d+%d" % (ww, wh, x, y))
    root .resizable(width=False, height=False)
    return root


def deploy_play(root):
    # 时间块
    global time_text
    frame_time = tk.Frame(root)
    frame_time.pack(fill='x')
    frame_time_center = tk.Frame(frame_time)
    frame_time_center.pack(anchor='center')
    tk.Label(frame_time_center, text="当前时间", ).pack(side="left")
    time_text = tk.Label(frame_time_center, anchor="w")
    time_text.pack(side="left")
    time_text.config(width=20)

    def asyn_time():
        global time_start
        time_start = False
        if isinstance(T, threading.Thread):
            T.join()
        start_time_thread()

    time_btn = tk.Button(frame_time_center, text='同步时间',
                         command=asyn_time, padx=(10.0),)
    time_btn.pack(side="left")

    # 公共抢购时间
    frame_start_time = tk.Frame(root)
    frame_start_time.pack(anchor='center')
    tk.Label(frame_start_time, text="抢购时间", ).pack(side="left")
    start_time_ent = tk.Entry(frame_start_time)
    start_time_ent.pack(side="left")
    start_time_ent.config(width=30)
    start_time_ent.insert(0, "2024-03-08 09:59:59.87900")

    def on_activity_id_change(*args):
        global activity_id
        print(activity_id_var.get().strip())
        activity_id = activity_id_var.get().strip()
    tk.Label(frame_start_time, text="activity_id",
             ).pack(side="left", ipadx=10)
    # 创建 StringVar 并将其与 Entry 绑定
    activity_id_var = tk.StringVar()
    activity_id_var.set(activity_id)
    activity_id_ent = tk.Entry(frame_start_time, textvariable=activity_id_var)
    activity_id_ent.pack(side="left")
    activity_id_ent.config(width=30)
    # 监听 Entry 内容变化
    activity_id_var.trace_add("write", on_activity_id_change)

    # 控制窗口
    frame_data = tk.Frame(root)
    frame_data.pack(fill='x')

    tk.Label(frame_data, text='Time：').grid(
        row=0, column=0, padx=(10, 0), pady=(10, 0))
    data_time = tk.Entry(frame_data, )
    data_time.grid(row=0, column=1, padx=(0, 0), pady=(10, 0))

    tk.Label(frame_data, text='cookies：').grid(
        row=0, column=2, padx=(10, 0), pady=(10, 0))
    data_cookies = tk.Entry(frame_data,)
    data_cookies.grid(row=0, column=3, padx=(0, 0), pady=(10, 0))

    tk.Label(frame_data, text='prize_id：').grid(
        row=0, column=4, padx=(10, 0), pady=(10, 0))
    values_s = ['10', '50', '100', '300']
    data_prize_id_ent = ttk.Combobox(
        master=frame_data,  # 父容器
        height=15,  # 高度,下拉显示的条目数量
        width=20,  # 宽度
        state="readonly",  # 设置状态 normal(可选可输入)、readonly(只可选)、 disabled
        cursor="arrow",  # 鼠标移动时样式 arrow, circle, cross, plus...
        font=("", 14),  # 字体
        values=values_s,  # 设置下拉框的选项
    )
    data_prize_id_ent.grid(row=0, column=5, padx=(0, 0),
                           pady=(10, 0), sticky="ew")
    data_prize_id_ent.set('300')

    frame_log = tk.Frame(root, padx=10, pady=10)
    frame_log.pack(fill=tk.BOTH, expand=True)

    # # 创建滚动条
    scrollbar = ttk.Scrollbar(frame_log, orient='vertical')
    scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

    frame_left = tk.Canvas(
        frame_log, yscrollcommand=scrollbar.set, highlightthickness=0)
    frame_left.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

    # # 设置滚动条的命令为Listbox的yview方法
    scrollbar.config(command=frame_left.yview)

    def on_button_click(index):
        for k in range(len(arr)):
            if arr[k]['index'] == index:
                arr[k]['switch'] = False
                if isinstance(arr[k]['threading'], threading.Thread):
                    arr[k]['threading'].join()
                # image_url = 'https://image.qll-times.com/2023/11/27f4cc77ecca4ec487752af9810eb23e.png'
                # captcha_data = [{'character': '金', 'index': 0}, {
                #     'character': '应', 'index': 1}]
                image_url, captcha_data = play_order(k)
                if image_url and captcha_data:
                    print(image_url)
                    print(captcha_data)
                    arr[k]['texts'] = captcha_data
                    arr[k]['image_url'] = image_url
                    play_sms(k)
                break

    def on_button_click_del(index):
        for k in range(len(arr)):
            if arr[k]['index'] == index:
                arr[k]['switch'] = False
                if isinstance(arr[k]['threading'], threading.Thread):
                    arr[k]['threading'].join()
                del arr[k]
                update_create_log()
                break
        else:
            print("No matching item found")

    def update_create_log():
        global offset_y
        offset_y = 0
        frame_left.delete("all")
        for item in arr:
            create_log(item)

    def create_log(obj):
        global offset_y
        global arr
        global arr_index
        # 创建自定义的Frame来包含文本和按钮
        entry_frame = tk.Frame(frame_left, background='#f1f1f1')

        item_text = f"index: {obj['index']}"

        # 在Frame中添加Label显示文本信息
        tk.Label(entry_frame, text=item_text,
                 background='#f1f1f1').pack(side=tk.LEFT)

        def on_start_time_change(*args):
            obj['start_time'] = datetime.datetime.strptime(
                start_time_var.get().strip(), '%Y-%m-%d %H:%M:%S.%f')
            print(arr)
        # 创建 StringVar 并将其与 Entry 绑定
        start_time_var = tk.StringVar()
        start_time_var.set(obj['start_time'])
        start_time = tk.Entry(entry_frame, textvariable=start_time_var)
        start_time.pack(side="left")
        start_time.config(width=28)
        start_time_var.trace_add("write", on_start_time_change)

        def on_prize_id_ent_change(event=None):
            obj['prize_id'] = prize_id_var.get().strip()
            print(arr)
        # 创建 StringVar 并将其与 Entry 绑定
        prize_id_var = tk.StringVar()
        prize_id_var.set(obj['prize_id'])
        prize_id_ent = ttk.Combobox(
            master=entry_frame,  # 父容器
            textvariable=prize_id_var,
            height=15,  # 高度,下拉显示的条目数量
            width=1,  # 宽度
            state="readonly",  # 设置状态 normal(可选可输入)、readonly(只可选)、 disabled
            cursor="arrow",  # 鼠标移动时样式 arrow, circle, cross, plus...
            font=("", 14),  # 字体
            values=values_s,  # 设置下拉框的选项
        )
        prize_id_ent.pack(side="left")
        prize_id_ent.config(width=6)
        prize_id_ent.bind("<<ComboboxSelected>>", on_prize_id_ent_change)

        obj['logbel'] = tk.Label(
            entry_frame, text=obj['texts'], background='#f1f1f1', width=60, anchor='w')
        obj['logbel'].pack(side=tk.LEFT, fill=tk.BOTH)
        # 在Frame中添加Button并将其与点击事件关联

        button = ttk.Button(entry_frame, text="获取验证码",
                            command=lambda: on_button_click(obj['index']))
        button.pack(side=tk.RIGHT)

        button_del = ttk.Button(entry_frame, text="删除",
                                command=lambda: on_button_click_del(obj['index']), width=3)
        button_del.pack(side=tk.RIGHT)

        entry_frame.update_idletasks()

        # 将entry_frame插入到Canvas中
        frame_left.create_window(
            (0, offset_y), window=entry_frame, anchor="nw", width=frame_left.winfo_width(), height=entry_frame.winfo_reqheight())
        # 更新偏移量
        offset_y = offset_y + entry_frame.winfo_reqheight()

        # 更新Canvas及滚动条
        frame_left.update_idletasks()
        frame_left.config(scrollregion=frame_left.bbox("all"))
        scrollbar.config(command=frame_left.yview)

    def submit():
        global arr_index
        start_time_text = data_time.get().strip() or start_time_ent.get().strip()
        if data_cookies.get().strip() == "":
            return
        obj = {
            'cookie': data_cookies.get().strip(),
            'start_time': datetime.datetime.strptime(start_time_text, '%Y-%m-%d %H:%M:%S.%f'),
            'prize_id': data_prize_id_ent.get().strip(),
            'image_url': '',
            'texts': [],
            'logbel': '',
            'index': arr_index,
            'switch': True,
            'threading': None
        }
        data_cookies.delete(0, 'end')
        data_time.delete(0, 'end')
        arr.append(obj)
        arr_index += 1
        update_create_log()

    def onEnter(e):
        submit()
    data_cookies.bind("<Return>", onEnter)
    btn = tk.Button(frame_data, text='提交', command=submit)
    btn.grid(row=0, column=99, columnspan=1, rowspan=1, padx=0, pady=(10, 10))


def main():
    '''主函数'''
    # 初始化窗口
    root = create_windows()
    # 运行窗口
    deploy_play(root)
    start_time_thread()
    # 进入主循环
    root.mainloop()


if __name__ == '__main__':
    main()
